<script setup lang="ts">
import { ref, reactive, h, onMounted } from "vue";
import { DynamicTable } from "@/components/DynamicTable";
import { PaginationConfig, TableColumn } from "@/components/DynamicTable/types";
import {
  ElMessage,
  ElTag,
  ElProgress,
  ElDialog,
  ElDescriptions,
  ElCard,
  ElButton,
  ElCollapse,
  ElCollapseItem,
} from "element-plus";
import { Refresh, DocumentCopy } from "@element-plus/icons-vue";
import { useClipboard } from "@vueuse/core";
import { getScanHistory, getScanResult } from "../servers";

const props = defineProps<{
  task: string;
}>();

const pagination = reactive<PaginationConfig>({
  currentPage: 1,
  pageSize: 10,
  total: 0,
  pageSizes: [10, 20, 50, 100],
  layout: "total, sizes, prev, pager, next",
  background: true,
});

const historyList = ref([]);
const loading = ref(false);

// 扫描结果对话框
const resultDialogVisible = ref(false);
const scanResult = ref<any[]>([]);
const scanDetail = ref<any>(null);

// 详情对话框
const detailDialogVisible = ref(false);
const detailData = ref<any>(null);
const { copy } = useClipboard();

const resultColumns = ref<TableColumn[]>([
  {
    label: "匹配位置",
    prop: "matched_at",
    minWidth: 250,
    show: true,
  },
  {
    label: "严重性",
    prop: "severity",
    width: 100,
    show: true,
    render: (row) => {
      const severityMap = {
        critical: { text: "严重", type: "danger" },
        high: { text: "高危", type: "danger" },
        medium: { text: "中等", type: "warning" },
        low: { text: "低危", type: "info" },
        info: { text: "信息", type: "" },
      };
      const item = severityMap[row.severity] || {
        text: row.severity,
        type: "danger",
      };
      return h(ElTag, { type: item.type, size: "small" }, () => item.text);
    },
  },
  {
    label: "状态码",
    prop: "status_code",
    width: 100,
    show: true,
  },
  {
    label: "提取结果",
    prop: "extracted_results",
    minWidth: 200,
    show: true,
    render: (row) => {
      if (Array.isArray(row.extracted_results)) {
        return row.extracted_results.join(", ");
      }
      return row.extracted_results || "-";
    },
  },
  {
    label: "CURL命令",
    prop: "curl_command",
    minWidth: 300,
    show: true,
    render: (row) => {
      if (!row.curl_command) return "-";
      return h(
        "code",
        {
          style: {
            fontFamily: "monospace",
            fontSize: "12px",
            wordBreak: "break-all",
            whiteSpace: "pre-wrap",
          },
        },
        row.curl_command
      );
    },
  },
  {
    label: "检测时间",
    prop: "created_at",
    width: 160,
    show: true,
  },
  {
    label: "操作",
    prop: "action",
    width: 120,
    show: true,
    slot: "result_action",
    fixed: "right",
  },
]);

const historyColumns = ref<TableColumn[]>([
  {
    label: "任务ID",
    prop: "task_id",
    width: 200,
    show: true,
  },
  {
    label: "漏洞名称",
    prop: "vulnerability_name",
    minWidth: 200,
    show: true,
  },
  {
    label: "目标URL",
    prop: "target_url",
    width: 200,
    show: true,
  },
  {
    label: "状态",
    prop: "status",
    width: 120,
    show: true,
    render: (row) => {
      const statusMap = {
        pending: { text: "等待中", type: "info" },
        running: { text: "扫描中", type: "warning" },
        success: { text: "成功", type: "success" },
        failed: { text: "失败", type: "danger" },
      };
      const item = statusMap[row.status] || { text: row.status, type: "" };
      return h(ElTag, { type: item.type, size: "small" }, () => item.text);
    },
  },
  {
    label: "进度",
    prop: "progress",
    width: 150,
    show: true,
    render: (row) => {
      return h(ElProgress, {
        percentage: row.progress || 0,
        status: row.status === "failed" ? "exception" : undefined,
      });
    },
  },
  {
    label: "扫描类型",
    prop: "scan_type",
    width: 100,
    show: true,
    render: (row) => (row.scan_type === "single" ? "单个" : "批量"),
  },
  // {
  //   label: "是否发现漏洞",
  //   prop: "has_vulnerability",
  //   width: 120,
  //   show: true,
  //   render: (row) => {
  //     if (row.has_vulnerability) {
  //       return h(ElTag, { type: "danger", size: "small" }, () => "发现漏洞");
  //     } else {
  //       return h(ElTag, { type: "success", size: "small" }, () => "未发现");
  //     }
  //   },
  // },
  {
    label: "操作",
    prop: "action",
    width: 150,
    show: true,
    slot: "history_action",
    fixed: "right",
  },
]);

const fetchScanHistory = async () => {
  loading.value = true;
  try {
    const params: any = {
      page: pagination.currentPage,
      per_page: pagination.pageSize,
    };
    const { data } = await getScanHistory(params);
    historyList.value = data.tasks || [];
    pagination.total = data.total || 0;
  } catch (error) {
    ElMessage.error("获取扫描历史失败");
  } finally {
    loading.value = false;
  }
};

const handlePageChange = (page: number) => {
  pagination.currentPage = page;
  fetchScanHistory();
};

const handleSizeChange = (size: number) => {
  pagination.pageSize = size;
  pagination.currentPage = 1;
  fetchScanHistory();
};

const viewScanResult = async (taskId: string) => {
  try {
    const { data } = await getScanResult(taskId);
    // data 包含 task_info, vulnerability_detail, results
    scanResult.value = data.results || [];
    scanDetail.value = {
      task_info: data.task_info,
      vulnerability_detail: data.vulnerability_detail,
      has_vulnerability:
        data.has_vulnerability || (data.results && data.results.length > 0),
    };
    resultDialogVisible.value = true;
  } catch (error) {
    ElMessage.error("获取扫描结果失败");
  }
};

// 查看详情
const handleViewDetail = (row: any) => {
  detailData.value = row;
  detailDialogVisible.value = true;
};

// 复制CURL命令
const handleCopyCurl = async (row: any) => {
  if (row.curl_command) {
    await copy(row.curl_command);
    ElMessage.success("已复制到剪贴板");
  }
};

onMounted(() => {
  fetchScanHistory();
});

defineExpose({
  fetchScanHistory,
});
</script>

<template>
  <div>
    <el-card>
      <DynamicTable
        :pagination="pagination"
        :columns="historyColumns"
        :data="historyList"
        :loading="loading"
        @current-page-change="handlePageChange"
        @size-change="handleSizeChange"
      >
        <template #toolbar-right>
          <el-button type="primary" :icon="Refresh" @click="fetchScanHistory">
            刷新
          </el-button>
        </template>
        <template #history_action="{ row }">
          <el-button
            :disabled="row.status !== 'success'"
            type="primary"
            size="small"
            @click="viewScanResult(row.task_id)"
          >
            查看结果
          </el-button>
          <el-button
            v-if="row.status === 'running'"
            type="info"
            size="small"
            disabled
            >扫描中...</el-button
          >
        </template>
      </DynamicTable>
    </el-card>

    <!-- 扫描结果对话框 -->
    <el-dialog
      v-model="resultDialogVisible"
      title="扫描结果"
      width="1200px"
      destroy-on-close
    >
      <!-- 任务信息 -->
      <div v-if="scanDetail?.task_info" style="margin-bottom: 20px">
        <el-card>
          <template #header>
            <strong>任务信息</strong>
          </template>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="任务ID">{{
              scanDetail.task_info.task_id
            }}</el-descriptions-item>
            <el-descriptions-item label="状态">
              <el-tag
                :type="
                  scanDetail.task_info.status === 'success'
                    ? 'success'
                    : scanDetail.task_info.status === 'failed'
                    ? 'danger'
                    : 'warning'
                "
                size="small"
              >
                {{
                  scanDetail.task_info.status === "success"
                    ? "成功"
                    : scanDetail.task_info.status === "failed"
                    ? "失败"
                    : scanDetail.task_info.status === "running"
                    ? "运行中"
                    : "等待中"
                }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="目标URL" :span="2">
              {{ scanDetail.task_info.target_url }}
            </el-descriptions-item>
            <el-descriptions-item label="进度">
              <el-progress
                :percentage="scanDetail.task_info.progress || 0"
                :status="
                  scanDetail.task_info.status === 'failed'
                    ? 'exception'
                    : undefined
                "
              />
            </el-descriptions-item>
            <el-descriptions-item label="扫描类型">
              {{
                scanDetail.task_info.scan_type === "single" ? "单个" : "批量"
              }}
            </el-descriptions-item>
            <el-descriptions-item label="创建时间">{{
              scanDetail.task_info.created_at
            }}</el-descriptions-item>
            <el-descriptions-item label="完成时间">
              {{ scanDetail.task_info.completed_at || "-" }}
            </el-descriptions-item>
          </el-descriptions>
        </el-card>
      </div>

      <!-- 漏洞信息 -->
      <div v-if="scanDetail?.vulnerability_detail" style="margin-bottom: 20px">
        <el-card>
          <template #header>
            <strong>漏洞信息</strong>
          </template>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="CVE ID">
              <a
                :href="scanDetail.vulnerability_detail.link"
                target="_blank"
                style="color: #409eff"
              >
                {{ scanDetail.vulnerability_detail.cve_id }}
              </a>
            </el-descriptions-item>
            <el-descriptions-item label="漏洞名称">{{
              scanDetail.vulnerability_detail.name
            }}</el-descriptions-item>
            <el-descriptions-item label="严重性">
              <el-tag
                :type="
                  scanDetail.vulnerability_detail.severity === 'critical'
                    ? 'danger'
                    : scanDetail.vulnerability_detail.severity === 'high'
                    ? 'warning'
                    : 'success'
                "
                size="small"
              >
                {{ scanDetail.vulnerability_detail.severity }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="CVSS评分">
              <span
                :style="
                  scanDetail.vulnerability_detail.cvss_score >= 9
                    ? 'color: #f56c6c; font-weight: bold'
                    : scanDetail.vulnerability_detail.cvss_score >= 7
                    ? 'color: #e6a23c; font-weight: bold'
                    : 'color: #409eff; font-weight: bold'
                "
              >
                {{ scanDetail.vulnerability_detail.cvss_score }}
              </span>
            </el-descriptions-item>
            <el-descriptions-item label="EPSS评分">
              {{
                scanDetail.vulnerability_detail.epss_score
                  ? (scanDetail.vulnerability_detail.epss_score * 100).toFixed(
                      2
                    ) + "%"
                  : "N/A"
              }}
            </el-descriptions-item>
            <el-descriptions-item label="CWE ID">{{
              scanDetail.vulnerability_detail.cwe_id || "N/A"
            }}</el-descriptions-item>
            <el-descriptions-item label="描述" :span="2">{{
              scanDetail.vulnerability_detail.description
            }}</el-descriptions-item>
            <el-descriptions-item label="修复建议" :span="2">
              <div style="white-space: pre-wrap">
                {{
                  scanDetail.vulnerability_detail.fix_suggestion ||
                  "暂无修复建议"
                }}
              </div>
            </el-descriptions-item>
          </el-descriptions>
        </el-card>
      </div>

      <!-- 检测结果 -->
      <el-card>
        <template #header>
          <div style="margin-bottom: 10px">
            <strong
              >检测结果 ({{
                scanDetail?.has_vulnerability ? "发现漏洞" : "未发现漏洞"
              }})</strong
            >
          </div>
        </template>
        <el-empty
          v-if="!scanResult || scanResult.length === 0"
          description="未发现漏洞"
          :image-size="100"
        />
        <DynamicTable
          v-else
          :columns="resultColumns"
          :data="scanResult"
          :loading="false"
          :pagination="{
            currentPage: 1,
            pageSize: 100,
            total: scanResult.length,
          }"
        >
          <template #result_action="{ row }">
            <el-button
              type="primary"
              size="small"
              @click="handleViewDetail(row)"
            >
              详情
            </el-button>
          </template>
        </DynamicTable>
      </el-card>
    </el-dialog>

    <!-- 详情对话框 -->
    <el-dialog
      v-model="detailDialogVisible"
      title="扫描结果详情"
      width="1000px"
      destroy-on-close
    >
      <div v-if="detailData" class="result-detail">
        <!-- 基本信息 -->
        <el-card shadow="never">
          <template #header>
            <strong>基本信息</strong>
          </template>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="匹配位置">
              {{ detailData.matched_at }}
            </el-descriptions-item>
            <el-descriptions-item label="状态码">
              <el-tag
                :type="detailData.status_code >= 500 ? 'danger' : 'success'"
              >
                {{ detailData.status_code }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="严重性">
              <el-tag
                :type="
                  detailData.severity === 'critical'
                    ? 'danger'
                    : detailData.severity === 'high'
                    ? 'warning'
                    : 'info'
                "
                size="small"
              >
                {{
                  detailData.severity === "critical"
                    ? "严重"
                    : detailData.severity === "high"
                    ? "高危"
                    : detailData.severity === "medium"
                    ? "中等"
                    : detailData.severity === "low"
                    ? "低危"
                    : "信息"
                }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="是否存在漏洞">
              <el-tag :type="detailData.is_vulnerable ? 'danger' : 'success'">
                {{ detailData.is_vulnerable ? "是" : "否" }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="提取结果" :span="2">
              <div v-if="Array.isArray(detailData.extracted_results)">
                <el-tag
                  v-for="(item, index) in detailData.extracted_results"
                  :key="index"
                  style="margin-right: 8px"
                >
                  {{ item }}
                </el-tag>
              </div>
              <div v-else>{{ detailData.extracted_results || "-" }}</div>
            </el-descriptions-item>
            <el-descriptions-item label="检测时间">
              {{ detailData.created_at }}
            </el-descriptions-item>
          </el-descriptions>
        </el-card>

        <div style="height: 16px"></div>

        <!-- CURL命令 -->
        <el-card v-if="detailData.curl_command" shadow="never">
          <template #header>
            <div class="card-header">
              <strong>复现命令</strong>
              <el-button
                :icon="DocumentCopy"
                size="small"
                @click="handleCopyCurl(detailData)"
              >
                复制
              </el-button>
            </div>
          </template>
          <pre class="code-block">{{ detailData.curl_command }}</pre>
        </el-card>

        <div v-if="detailData.curl_command" style="height: 16px"></div>

        <!-- HTTP 请求和响应 -->
        <el-collapse v-if="detailData.request || detailData.response">
          <!-- HTTP 请求 -->
          <el-collapse-item
            v-if="detailData.request"
            title="HTTP 请求详情"
            name="request"
          >
            <pre class="code-block">{{ detailData.request }}</pre>
          </el-collapse-item>

          <!-- HTTP 响应 -->
          <el-collapse-item
            v-if="detailData.response"
            title="HTTP 响应详情"
            name="response"
          >
            <pre class="code-block">{{ detailData.response }}</pre>
          </el-collapse-item>
        </el-collapse>

        <!-- 模板信息 -->
        <div v-if="detailData.info" style="margin-top: 16px">
          <el-card shadow="never">
            <template #header>
              <strong>模板信息</strong>
            </template>
            <el-descriptions :column="2" border>
              <el-descriptions-item label="模板名称">{{
                detailData.info.name
              }}</el-descriptions-item>
              <el-descriptions-item label="严重性">
                <el-tag
                  :type="
                    detailData.info.severity === 'critical'
                      ? 'danger'
                      : detailData.info.severity === 'high'
                      ? 'warning'
                      : 'info'
                  "
                  size="small"
                >
                  {{ detailData.info.severity }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="作者" :span="2">
                <div v-if="Array.isArray(detailData.info.author)">
                  <el-tag
                    v-for="(author, index) in detailData.info.author"
                    :key="index"
                    style="margin-right: 8px"
                  >
                    {{ author }}
                  </el-tag>
                </div>
                <div v-else>{{ detailData.info.author }}</div>
              </el-descriptions-item>
              <el-descriptions-item label="标签">
                <div v-if="Array.isArray(detailData.info.tags)">
                  <el-tag
                    v-for="(tag, index) in detailData.info.tags"
                    :key="index"
                    type="success"
                    style="margin-right: 8px"
                  >
                    {{ tag }}
                  </el-tag>
                </div>
                <div v-else>{{ detailData.info.tags }}</div>
              </el-descriptions-item>
              <el-descriptions-item label="描述" :span="2">
                {{ detailData.info.description }}
              </el-descriptions-item>
            </el-descriptions>
          </el-card>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.result-detail {
  max-height: 70vh;
  overflow-y: auto;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.code-block {
  background: #2d2d2d;
  color: #f8f8f2;
  padding: 16px;
  border-radius: 4px;
  font-family: "Courier New", Courier, monospace;
  font-size: 13px;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  margin: 0;
}

:deep(.el-collapse) {
  border: none;
}

:deep(.el-collapse-item__header) {
  padding: 12px 0;
  font-weight: 600;
}

:deep(.el-collapse-item__content) {
  padding: 12px 0;
}
</style>
